package com.wnxy.sk.order.mq;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.rabbitmq.client.Channel;
import com.wnxy.sk.order.constant.OrderConstant;
import com.wnxy.sk.order.dto.OrderPayDto;
import com.wnxy.sk.order.entity.Order;
import com.wnxy.sk.order.service.IOrderService;
import com.wnxy.sk.order.vo.OrderVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Component;

import java.io.IOException;

@Component
@Slf4j
public class OrderConsumer {
    @Autowired
    private IOrderService orderService;
    @Autowired
    private RedisTemplate redisTemplate;

    @RabbitHandler
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "order-dead-letter-queue", durable = "true",
                    autoDelete = "false", exclusive = "false"),
            exchange = @Exchange(value = "order-dead-letter-exchange", durable = "true",
                    autoDelete = "false", type = ExchangeTypes.TOPIC),
            key = "dead.letter.order")
    )
    public void handleOrder(@Payload OrderPayDto orderPayDto, Channel channel, Message message) {

        log.info("消费死信队列中的超时消息 {}",orderPayDto);

        //判断从mq中获取到的超时数据，订单的状态是否为待支付，如果为待支付状态，则更新订单失效。
        OrderVo orderVo = orderService.getOrderBySn(orderPayDto.getOrderSn());

        if (orderVo.getStatus().equals(OrderConstant.ORDER_TYPE_NORMAL)) {//0待付款

            log.info("订单失效,修改订单状态为5，无效订单");

            LambdaUpdateWrapper<Order> updateWrapper = Wrappers.lambdaUpdate();
            updateWrapper.set(Order::getStatus, OrderConstant.INVALID);//已失效
            updateWrapper.eq(Order::getOrderSn, orderPayDto.getOrderSn());
            orderService.update(updateWrapper);

            //将redis中扣减的库存，还原
            redisTemplate.opsForList().leftPush(
                    "seckill:count:" + orderPayDto.getPromotionId(),
                    orderPayDto.getProductId());
        }
        try {
            //手动应答
            log.info("channel.basicAck start");
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            log.info("channel.basicAck end");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}